﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.IO;

namespace CodeCounsel.SharePoint.RibbonDesigner.Model
{
    [Serializable, 
    TypeConverter(typeof(RibbonIdConverter))]
    public class RibbonId
    {
        const string _replacementIdFragment = "_children";
        bool _isReplacementId;
        
        public IEnumerable<string> Fragments { get; private set; }
        public string RawValue{ get; private set;}

        public bool IsReplacementId
        {
            get { return _isReplacementId; }
        }
        
        public string LocalId
        {
            get { return Fragments.Last(); }
        }

        public string Id
        {
            get { return String.Join(".", Fragments); }
        }

        public RibbonId(string rawValue)
        {
            if (String.IsNullOrEmpty(rawValue))
            {
                throw new ArgumentNullException("rawValue");
            }
            string[] parts = rawValue.Split('.');
            _isReplacementId = String.Equals(
                parts.Last(), 
                _replacementIdFragment, 
                StringComparison.OrdinalIgnoreCase) == false;
            if (parts.Length == 1 && _isReplacementId == false)
            {
                throw new ArgumentOutOfRangeException();
            }
            Fragments = _isReplacementId ? parts : parts.Take(parts.Length - 1);
            RawValue = rawValue;
        }

        public override bool Equals(object obj)
        {
            RibbonId otherId = obj as RibbonId;
            return otherId != null && Equals(otherId);
        }

        public bool Equals(RibbonId obj)
        {
            return Id == obj.Id;
        }

        public override int GetHashCode()
        {
            return RawValue.GetHashCode();
        }

        public bool IsParentOf(RibbonId otherId)
        {
            return otherId.Id.StartsWith(Id);
        }

        public bool IsChildOf(RibbonId otherId)
        {
            return Id.StartsWith(otherId.Id);
        }

        public override string ToString()
        {
            return RawValue;
        }

        public static implicit operator string(RibbonId id)
        {
            return id != null ? id.RawValue : null;
        }

        public static implicit operator RibbonId(string id)
        {
            return new RibbonId(id);
        }

        public static bool operator ==(RibbonId a, RibbonId b)
        {
            if (System.Object.ReferenceEquals(a, b))
            {
                return true;
            }
            if (((object)a == null) || ((object)b == null))
            {
                return false;
            }
            return a.Id == b.Id;
        }

        public static bool operator !=(RibbonId a, RibbonId b)
        {
            return !(a == b);
        }
    }
}
